package Comp;

/**
 * This class converts a non-parenthesis infix expression to a prefix expression.
 * <p><b>Original Author:</b>  Yogesh Jindal
 */
public class NoParenthesis {
    String[] label_array = new String[1000]; int label_pointer=-1;
    String[] opert_array = new String[10]; int opert_pointer=-1;
    
   // public NoParenthesis() {        
   // }
    
    /**
     * This function increments the label_pointer and put the parameter string into that index of
     * label_array.<p>
     * Modified Log:<br>
     * 5/10/08 - Edited documentation - Keith Hill<br>
     * <p>
     * Error Condition tested:<br> 
     * None<br>
     * <p>
     * Creation Date : May 5,2008
     * <p>
     * <b>Original Author:</b> Yogesh Jindal
     * @param label The label to be pushed on the top of the label_array[].   
     */
    private void pushLabel(String label){
        label_pointer++;
        label_array[label_pointer] = label;
    }
    
    /**
     * This function checks the priority of opert(a valid operator) and converts the infix 
     * expression to prefix expression accordingly.<p>
     * Modified Log:<br>
     * 5/10/08 - Edited documentation - Keith Hill<br>
     * <p>
     * Error Condition tested:<br>
     * None<br>
     * <p>
     * Creation Date : May 5,2008<p>
     * <b>Original Author:</b> Yogesh Jindal
     * @param opert Any operator out of + - * /
     */
    private void pushOpert(String opert){
       if(opert_pointer==-1){
           opert_pointer++;
           opert_array[opert_pointer] = opert;
           return;
       }
       if(isHigherPriority(opert_array[opert_pointer], opert)==1){//solve it
           String temp = opert_array[opert_pointer];
           temp += label_array[label_pointer-1]+label_array[label_pointer];
           label_array[label_pointer-1] = temp;
           label_pointer-=1;
           opert_array[opert_pointer] = opert;
           while(opert_pointer>0 && isHigherPriority(opert_array[opert_pointer-1], opert_array[opert_pointer])==1){
               String temp2 = opert_array[opert_pointer-1];
               temp2 += label_array[label_pointer-1]+label_array[label_pointer];
               label_array[label_pointer-1] = temp2;
               label_pointer--;
               opert_array[opert_pointer-1] = opert_array[opert_pointer];
               opert_pointer--;
           }
           /*if(opert_pointer>=1){
               if( isHigherPriority(opert_array[0], opert_array[1])==1){//solve it
                   temp = opert_array[0];
                   temp += label_array[label_pointer-1]+label_array[label_pointer];
                   label_array[label_pointer-1] = temp;
               }
           }*/
       }else{
           opert_pointer++;
           opert_array[opert_pointer] = opert;
           return;
       }
    }
    
    /**
     * This function combines the label_array[] and opert_array[] according to the prefix rules.<p>
     * <p>
     * Modified Log:<br>
     * 5/10/08 - Fixed documentation - Keith Hill<br>
     * <p>
     * Error Condition tested:<br>
     * None<br>
     * <p>
     * Creation Date : May 5,2008
     * <p>
     * <b>Original Author:</b> Yogesh Jindal
     */
    private void endOfArray(){
        if(opert_pointer==-1){
            return;
        }
        while(opert_pointer!=-1){
           String temp = opert_array[opert_pointer];
           temp += label_array[label_pointer-1]+label_array[label_pointer];
           label_array[label_pointer-1] = temp;
           label_pointer-=1; opert_pointer--;
        }
    }
    
    /**
     * This function converts a non parenthesis infix String[] into a prefix String.
     * <p>
     * Modified Log:<br>
     * 5/10/08 - Edited documentation - Keith Hill<br>
     * <p>
     * Error Condition tested:<br>
     * None<br>
     * <p>
     * Creation Date : May 5,2008
     * <p>
     * <b>Original Author:</b> Yogesh Jindal
     * @param array The infix String[] without any parenthesis.
     * @return Returns a prefix String.
     */
    protected String handleNoParenthesis(String[] array){
        for(int index=0; index<array.length; index++){
            if(isOperator(array[index])==1){
                pushOpert(array[index]);
            }else{
                pushLabel(array[index]);
            }
        }
        endOfArray();
        return label_array[0];
    }
    
    /**
     * This function checks if the parameter string is an operator out of - + * / 
     * <p>
     * Modified Log:<br>
     * 5/10/08 - Edited documentation - Keith Hill<br>
     * <p>
     * Error Condition tested:<br>
     * None<br>
     * <p>
     * Creation Date : May 5,2008<p>
     * <b>Original Author:</b> Yogesh Jindal
     * @param check_operator The string to be checked for an operator.
     * @return Returns 1 for an operator else returns 0.
     */    
    private int isOperator(String check_operator){
        String[] operators = {"+","-","*","/"};
        for(int index=0; index<operators.length; index++){
            if(operators[index].contentEquals(check_operator)){
                return 1;
            }
        }
        return 0;
    }
    
    /**
     * This function checks the priority of two operators(- + * or /).
     * <p>
     * Modified Log:<br>
     * None<br>
     * <p>
     * Error Condition tested:<b> 
     * None<br>
     * <p>
     * Creation Date : May 5,2008
     * <p>
     * <b>Original Author:</b> Yogesh Jindal
     * @param op1 An operator(- + * or /).
     * @param op2 An operator(- + * or /).
     * @return - Returns 0 if op1 has less priority than op2 else returns 1.
     */
    private int isHigherPriority(String op1, String op2){
        int num1=0,num2=0;
        String[] operators = {"-","+","*","/"};
        for(int index=0; index<operators.length; index++){
            if(operators[index].contentEquals(op1)){
                num1=index; break;
            }            
        }
        for(int index=0; index<operators.length; index++){
            if(operators[index].contentEquals(op2)){
                num2=index; break;
            }
        }
        if(num1<num2){
            return 0;
        }        
        return 1;
    }
}